/*
 * @Author: bor_fish 1219854025@qq.com
 * @Date: 2025-04-22 15:22:34
 * @LastEditors: bor_fish 1219854025@qq.com
 * @LastEditTime: 2025-05-21 10:40:08
 * @FilePath: /myCAN/Listener.h
 */

#pragma once
#include <vector>
#include <linux/can.h>
#include <mutex>
#include <shared_mutex>
#include <array>
#include <condition_variable>
#include <atomic>
#include <queue>

class CanListener
{
protected:
    //几路CAN设备，目前三路
    static constexpr size_t kCanSize = 3;
    //每路CAN设备存储数据缓冲区大小，同一路CAN可以存放6000个数据包       
    static constexpr size_t kBufferSize = 6000;
    //每个数据包大小
    static constexpr size_t kFrameSize = 100;
    //设备名称
    const std::string kInterfaceName[kCanSize] =  {"vcan0"};
    // 诊断线程数量
    static constexpr int kDiagnosticThreadCount = 3; 

    //全局进程运行标志位
    static std::atomic<bool> global_running_;

    // 广播机制相关
    // 每个诊断线程的独立队列
    std::array<std::queue<std::pair<can_frame, int>>, 
    kDiagnosticThreadCount> broadcast_queues_;  
    // 每个队列的互斥锁
    std::array<std::mutex, kDiagnosticThreadCount> broadcast_mutexes_;  
    // 每个队列的条件变量
    std::array<std::condition_variable, kDiagnosticThreadCount> broadcast_cvs_;  
    // 记录已处理的线程数量（原子操作）
    std::atomic<int> processed_count_{0};
   

    
    //存放CAN套接字
    std::vector<int> can_sockets_;
    // 互斥锁，用于保护全局缓冲区
    std::mutex linstener_mutex_;
    //存放写入数据的下标索引
    std::array<int, kCanSize> write_indices_{};
    //存放 数据包 缓冲区
    std::array<std::array<std::array<unsigned char , kFrameSize>,
    kBufferSize>, kCanSize> packet_Buffer_{};

public:
    //监听线程函数
    void Sockets_Init(void);
    void Listen_Loop(void);
    void ProcessData(const can_frame& frame, int interface_index);
    void Stop(void);//main调用
    void printBufDebugInfo(const can_frame& frame, int interface_index
        , int packet_index);//Debug

    // 广播数据到所有诊断线程
    void broadcastData(const can_frame& frame, int interface_index);  

    // 诊断线程调用方法
    bool getNextData(can_frame& frame, int& interface_index, int thread_index);
    static bool isRunning() {
        return global_running_.load(std::memory_order_acquire);
    }
    void notifyDataProcessed();  // 通知数据已处理

    //对外访问接口方法
    // 获取数据包 packet_Buffer_
    std::array<std::array<std::array<unsigned char, kFrameSize>, kBufferSize>, kCanSize>& 
    getPacketBuffer()  { return packet_Buffer_; }
    // 获取写入索引
    int getWriteIndex(int interface_index) const { return write_indices_[interface_index]; }
    // 获取CAN接口数量  
    static constexpr size_t getCanSize() { return kCanSize; }
    // 获取缓冲区大小 kBufferSize
    static constexpr size_t getBufferSize() { return kBufferSize; }
    // 获取帧大小
    static constexpr size_t getFrameSize() { return kFrameSize; }
    // 获取已处理的包数
    int getProcessedCount() const { return processed_count_.load(std::memory_order_acquire); }
      
    // CRC-15 CAN实现
    uint16_t calc_can_crc(const uint8_t* data, size_t len) {
    uint16_t crc = 0;
    for (size_t i = 0; i < len; ++i) {
        crc ^= (uint16_t)data[i] << 7;
        for (int j = 0; j < 8; ++j) {
            if (crc & 0x4000)
                crc = (crc << 1) ^ 0x4599;
            else
                crc <<= 1;
        }
    }
    return (crc >> 1) & 0x7FFF; // 15位
    }



};
